package tianxiao.web.test;

import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.extra.servlet.multipart.MultipartFormData;
import cn.hutool.extra.servlet.multipart.UploadFile;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import tianxiao.web.test.common.HelloReqAtta;
import yun.web.activerecord.Page;
import yun.web.activerecord.Record;
import yun.web.enjoy.kit.Kv;
import yun.web.springmvc.ext.View;
import yun.web.springmvc.interceptor.Clear;
import yun.web.springmvc.interceptor.Interceptors;
import yun.web.springmvc.paramcheck.ParamCheck;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Random;

@Interceptors({HelloInterceptor.class})
@RestController
public class HelloController {

    Log log = LogFactory.get("HelloController");

    // ${} 与 Kotlin字符串模板冲突, 改为JFinal Enjoy风格
    @Value("#(environments.dev.url)")
    String app_id;

    @Value("#(cache.cache:false)")
    Boolean cache;

    @Resource
    HelloService helloService;

    @GetMapping("/log")
    public Object log(){
        log.debug("我是json");
        log.info("我是json");
        log.warn("我是json");
        log.error("我是json");
        return View.build().set("log...");
    }

    @GetMapping("/index.html")
    public Object from() {
        Record record = Record.build("id", 1, "realname", "张天笑", "email", "920950604@qq.com");
        return new Random().nextDouble() > 0.5 ? View.view("/index.html").set("record", record) : "/index.html";
    }


    // 转发测试
    @GetMapping("/from")
    public View from(Kv kv) {
        return View.view("forward:/to").set("k1", "v1");
    }

    // 这个View来自转发, 作用只是传递数据
    @GetMapping("/to")
    public View to(View v) {
        // 如果想返回View内的数据, 手动清空Vp
        return v.setVp(null);
    }


    /*author: 张天笑
     返回json: http://localhost:3123/json
     */
    @Interceptors({HelloInterceptor.class})
    @Clear    // 清除所有拦截器
    @GetMapping("/json")
    public View index() {
        HashMap<String, String> map = new HashMap<>();
        map.put("a", "b");
        return View.build()
                .header("test", 123)
                .header("hehe", 234)
                .set(map);
    }

    /*author: 张天笑,
    二维码: http://localhost:3123/qrcodex
    */
    @Clear(HelloInterceptor.class)
    @GetMapping("/qrcodex")
    public View qrcode(String name) {
        return View.build().qrCode("http://www.baidu.com", 200, 200);
    }


    /*
    author: 张天笑
    形参注入: http://localhost:3123/model?user.name=123&user.age=234&user.strings=1&user.strings=2&decimal=123&lon=1111111111
    -*/
    @Interceptors({HelloInterceptor.class})
    @GetMapping("/model")
    public HashMap<String, Object> model(User user, BigDecimal decimal, Long lon,
                                         @CookieValue String sessionId,
                                         Kv kv,
                                         HelloReqAtta helloReqAtta,
                                         HttpServletRequest req,
                                         HttpServletResponse resp) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("decimal", decimal);
        map.put("lon", lon);
        return map;
    }

    /*author: 张天笑,
      下载文件: http://localhost:3123/file/1.jpg
      */
    @GetMapping("/file/{name}")
    public View downLoadFile(@PathVariable String name) {
        System.out.println(name);
        return View.build().download(new File("webapp/download.png"), "download.png");
    }

    /*author: 张天笑,
      文件预览: http://localhost:3123/preview/1.jpg
      */
    @GetMapping("/preview/{name}")
    public View previewFile(@PathVariable String name) {
        System.out.println(name);// 1.jpg
        return View.build().preview(new File("webapp/download.png"), "download.png");
    }


    /*author: 张天笑
      上传文件 , 不建议直接读req, 调用ServletUtil读, 通过第二个参数限制大小更为安全.
      当存在@MultpartFile注解, springboot就会直接读req到内存, 我即便在WebMvcConfigure中配置了, 它依旧会把文件完整的读进内存.撑爆jvm 当时的版本是 springboot1.5.2
    -*/
    @PostMapping("/upload")
    public HashMap upload(HttpServletRequest req) {
        MultipartFormData multipart = ServletUtil.getMultipart(req);
        UploadFile file = multipart.getFile("file");
        HashMap<String, String> map = new HashMap<>();
        map.put("a", file.getFileName());
        return map;
    }


    /**
     * author: 张天笑
     * 参数校验
     * http://localhost:3123/paramCheck
     *
     * @see HelloService#checkParam, 此处方法形参应与controller一致
     * 将
     */
    /*@ParamCheck("HelloService#checkParam")
    @GetMapping("/paramCheck")
    public HashMap paramCheck(String name) {
        return new HashMap();
    }*/
    @ParamCheck("tianxiao.web.test.HelloService#checkParam")
    @GetMapping("/paramCheck")
    public HashMap paramCheck(String name) {
        return new HashMap();
    }


    /*
          author: 张天笑
         Db + 缓存测试
      http://localhost:3123/db
    -*/
    @GetMapping("/db")
    public Record db() {
        return helloService.db("it");
    }

    /*
          author: 张天笑
       http://localhost:3123/paginate?lont=10&createtime=10
    -*/
    @GetMapping("/paginate")
    public Page<Record> paginate(Kv kv) {
        return helloService.paginate(1, 10, "test.find", kv);
    }


    /*
          author: 张天笑
       事务测试
       http://localhost:3123/dbTx
    -*/
    @GetMapping("/dbTx")
    public Boolean dbTx() {
        return helloService.dbTx("it");
    }

    /*author: 张天笑
     全局异常拦截测试: http://localhost:3123/exception

    -*/
    @GetMapping("/exception")
    public void exception() {
        int x = 1 / 0;
    }


    /*
    /*
    public static void main(String[] args) {
        System.out.println("AES 执行1w次, 平均耗时");
        testAes();

        System.out.println("MD5 执行1w次, 平均耗时");
        testMd5();

    }

    static void testAes() {
        byte[] sk = "1234567890123456".getBytes();
        AES aes = SecureUtil.aes(sk);

        long a = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            aes.encrypt("" + i);
        }
        System.out.println((System.currentTimeMillis() - a) / 10000.0);
    }

    static void testMd5() {
        long a = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            SecureUtil.md5("" + i);
        }
        System.out.println((System.currentTimeMillis() - a) / 10000.0);
    }
    */

    /*

    In Java,
     redis.client.sendCMD( cmd1 );
     redis.client.sendCMD( cmd2 );


     */
}
